#!perl

use strict;
use warnings;

use Test::More tests => 1021;

my $class;

BEGIN {
    $class = 'Math::BigInt';
    use_ok($class);
}

while (<DATA>) {
    s/#.*$//;                   # remove comments
    s/\s+$//;                   # remove trailing whitespace
    next unless length;         # skip empty lines

    my ($a, $n, $b, $expected) = split /:/;

    # buparrow() modifies the invocand.

    {
        my ($x, $y);
        my $test = qq|\$x = $class->new("$a"); \$y = \$x->buparrow($n, $b);|;

        subtest $test,
          sub {
              plan tests => 4;

              eval $test;
              is($@, "", "'$test' gives emtpy \$\@");

              is(ref($y), $class,
                 "'$test' output arg is a $class");

              is($y -> bstr(), $expected,
                 "'$test' output arg has the right value");

              is($x -> bstr(), $expected,
                 "'$test' invocand has the right value");
          };
    }

    # uparrow() does not modify the invocand.

    {
        my ($x, $y);
        my $test = qq|\$x = $class->new("$a"); \$y = \$x->uparrow($n, $b);|;

        subtest $test,
          sub {
              plan tests => 4;

              eval $test;
              is($@, "", "'$test' gives emtpy \$\@");

              is(ref($y), $class,
                 "'$test' output arg is a $class");

              is($y -> bstr(), $expected,
                 "'$test' output arg has the right value");

              is($x -> bstr(), $a,
                 "'$test' invocand has the right value");
          };
    }
}

__DATA__
0:0:0:0
0:0:1:0
0:0:2:0
0:0:3:0
0:0:4:0
0:0:5:0
0:0:6:0
0:0:7:0
0:0:8:0
0:0:9:0
0:1:0:1
0:1:1:0
0:1:2:0
0:1:3:0
0:1:4:0
0:1:5:0
0:1:6:0
0:1:7:0
0:1:8:0
0:1:9:0
0:2:0:1
0:2:1:0
0:2:2:1
0:2:3:0
0:2:4:1
0:2:5:0
0:2:6:1
0:2:7:0
0:2:8:1
0:2:9:0
0:3:0:1
0:3:1:0
0:3:2:1
0:3:3:0
0:3:4:1
0:3:5:0
0:3:6:1
0:3:7:0
0:3:8:1
0:3:9:0
0:4:0:1
0:4:1:0
0:4:2:1
0:4:3:0
0:4:4:1
0:4:5:0
0:4:6:1
0:4:7:0
0:4:8:1
0:4:9:0
0:5:0:1
0:5:1:0
0:5:2:1
0:5:3:0
0:5:4:1
0:5:5:0
0:5:6:1
0:5:7:0
0:5:8:1
0:5:9:0
0:6:0:1
0:6:1:0
0:6:2:1
0:6:3:0
0:6:4:1
0:6:5:0
0:6:6:1
0:6:7:0
0:6:8:1
0:6:9:0
0:7:0:1
0:7:1:0
0:7:2:1
0:7:3:0
0:7:4:1
0:7:5:0
0:7:6:1
0:7:7:0
0:7:8:1
0:7:9:0
0:8:0:1
0:8:1:0
0:8:2:1
0:8:3:0
0:8:4:1
0:8:5:0
0:8:6:1
0:8:7:0
0:8:8:1
0:8:9:0
0:9:0:1
0:9:1:0
0:9:2:1
0:9:3:0
0:9:4:1
0:9:5:0
0:9:6:1
0:9:7:0
0:9:8:1
0:9:9:0
1:0:0:0
1:0:1:1
1:0:2:2
1:0:3:3
1:0:4:4
1:0:5:5
1:0:6:6
1:0:7:7
1:0:8:8
1:0:9:9
1:1:0:1
1:1:1:1
1:1:2:1
1:1:3:1
1:1:4:1
1:1:5:1
1:1:6:1
1:1:7:1
1:1:8:1
1:1:9:1
1:2:0:1
1:2:1:1
1:2:2:1
1:2:3:1
1:2:4:1
1:2:5:1
1:2:6:1
1:2:7:1
1:2:8:1
1:2:9:1
1:3:0:1
1:3:1:1
1:3:2:1
1:3:3:1
1:3:4:1
1:3:5:1
1:3:6:1
1:3:7:1
1:3:8:1
1:3:9:1
1:4:0:1
1:4:1:1
1:4:2:1
1:4:3:1
1:4:4:1
1:4:5:1
1:4:6:1
1:4:7:1
1:4:8:1
1:4:9:1
1:5:0:1
1:5:1:1
1:5:2:1
1:5:3:1
1:5:4:1
1:5:5:1
1:5:6:1
1:5:7:1
1:5:8:1
1:5:9:1
1:6:0:1
1:6:1:1
1:6:2:1
1:6:3:1
1:6:4:1
1:6:5:1
1:6:6:1
1:6:7:1
1:6:8:1
1:6:9:1
1:7:0:1
1:7:1:1
1:7:2:1
1:7:3:1
1:7:4:1
1:7:5:1
1:7:6:1
1:7:7:1
1:7:8:1
1:7:9:1
1:8:0:1
1:8:1:1
1:8:2:1
1:8:3:1
1:8:4:1
1:8:5:1
1:8:6:1
1:8:7:1
1:8:8:1
1:8:9:1
1:9:0:1
1:9:1:1
1:9:2:1
1:9:3:1
1:9:4:1
1:9:5:1
1:9:6:1
1:9:7:1
1:9:8:1
1:9:9:1
2:0:0:0
2:0:1:2
2:0:2:4
2:0:3:6
2:0:4:8
2:0:5:10
2:0:6:12
2:0:7:14
2:0:8:16
2:0:9:18
2:1:0:1
2:1:1:2
2:1:2:4
2:1:3:8
2:1:4:16
2:1:5:32
2:1:6:64
2:1:7:128
2:1:8:256
2:1:9:512
2:2:0:1
2:2:1:2
2:2:2:4
2:2:3:16
2:2:4:65536
2:3:0:1
2:3:1:2
2:3:2:4
2:3:3:65536
2:4:0:1
2:4:1:2
2:4:2:4
2:5:0:1
2:5:1:2
2:5:2:4
2:6:0:1
2:6:1:2
2:6:2:4
2:7:0:1
2:7:1:2
2:7:2:4
2:8:0:1
2:8:1:2
2:8:2:4
2:9:0:1
2:9:1:2
2:9:2:4
3:0:0:0
3:0:1:3
3:0:2:6
3:0:3:9
3:0:4:12
3:0:5:15
3:0:6:18
3:0:7:21
3:0:8:24
3:0:9:27
3:1:0:1
3:1:1:3
3:1:2:9
3:1:3:27
3:1:4:81
3:1:5:243
3:1:6:729
3:1:7:2187
3:1:8:6561
3:1:9:19683
3:2:0:1
3:2:1:3
3:2:2:27
3:2:3:7625597484987
3:3:0:1
3:3:1:3
3:3:2:7625597484987
3:4:0:1
3:4:1:3
3:5:0:1
3:5:1:3
3:6:0:1
3:6:1:3
3:7:0:1
3:7:1:3
3:8:0:1
3:8:1:3
3:9:0:1
3:9:1:3
4:0:0:0
4:0:1:4
4:0:2:8
4:0:3:12
4:0:4:16
4:0:5:20
4:0:6:24
4:0:7:28
4:0:8:32
4:0:9:36
4:1:0:1
4:1:1:4
4:1:2:16
4:1:3:64
4:1:4:256
4:1:5:1024
4:1:6:4096
4:1:7:16384
4:1:8:65536
4:1:9:262144
4:2:0:1
4:2:1:4
4:2:2:256
4:2:3:13407807929942597099574024998205846127479365820592393377723561443721764030073546976801874298166903427690031858186486050853753882811946569946433649006084096
4:3:0:1
4:3:1:4
4:4:0:1
4:4:1:4
4:5:0:1
4:5:1:4
4:6:0:1
4:6:1:4
4:7:0:1
4:7:1:4
4:8:0:1
4:8:1:4
4:9:0:1
4:9:1:4
5:0:0:0
5:0:1:5
5:0:2:10
5:0:3:15
5:0:4:20
5:0:5:25
5:0:6:30
5:0:7:35
5:0:8:40
5:0:9:45
5:1:0:1
5:1:1:5
5:1:2:25
5:1:3:125
5:1:4:625
5:1:5:3125
5:1:6:15625
5:1:7:78125
5:1:8:390625
5:1:9:1953125
5:2:0:1
5:2:1:5
5:2:2:3125
5:2:3:1911012597945477520356404559703964599198081048990094337139512789246520530242615803012059386519739850265586440155794462235359212788673806972288410146915986602087961896757195701839281660338047611225975533626101001482651123413147768252411493094447176965282756285196737514395357542479093219206641883011787169122552421070050709064674382870851449950256586194461543183511379849133691779928127433840431549236855526783596374102105331546031353725325748636909159778690328266459182983815230286936572873691422648131291743762136325730321645282979486862576245362218017673224940567642819360078720713837072355305446356153946401185348493792719514594505508232749221605848912910945189959948686199543147666938013037176163592594479746164220050885079469804487133205133160739134230540198872570038329801246050197013467397175909027389493923817315786996845899794781068042822436093783946335265422815704302832442385515082316490967285712171708123232790481817268327510112746782317410985888683708522000711733492253913322300756147180429007527677793352306200618286012455254243061006894805446584704820650982664319360960388736258510747074340636286976576702699258649953557976318173902550891331223294743930343956161328334072831663498258145226862004307799084688103804187368324800903873596212919633602583120781673673742533322879296907205490595621406888825991244581842379597863476484315673760923625090371511798941424262270220066286486867868710182980872802560693101949280830825044198424796792058908817112327192301455582916746795197430548026404646854002733993860798594465961501752586965811447568510041568687730903712482535343839285397598749458497050038225012489284001826590056251286187629938044407340142347062055785305325034918189589707199305662188512963187501743535960282201038211616048545121039313312256332260766436236688296850208839496142830484739113991669622649948563685234712873294796680884509405893951104650944137909502276545653133018670633521323028460519434381399810561400652595300731790772711065783494174642684720956134647327748584238274899668755052504394218232191357223054066715373374248543645663782045701654593218154053548393614250664498585403307466468541890148134347714650315037954175778622811776585876941680908203125
5:3:0:1
5:3:1:5
5:4:0:1
5:4:1:5
5:5:0:1
5:5:1:5
5:6:0:1
5:6:1:5
5:7:0:1
5:7:1:5
5:8:0:1
5:8:1:5
5:9:0:1
5:9:1:5
6:0:0:0
6:0:1:6
6:0:2:12
6:0:3:18
6:0:4:24
6:0:5:30
6:0:6:36
6:0:7:42
6:0:8:48
6:0:9:54
6:1:0:1
6:1:1:6
6:1:2:36
6:1:3:216
6:1:4:1296
6:1:5:7776
6:1:6:46656
6:1:7:279936
6:1:8:1679616
6:1:9:10077696
6:2:0:1
6:2:1:6
6:2:2:46656
6:3:0:1
6:3:1:6
6:4:0:1
6:4:1:6
6:5:0:1
6:5:1:6
6:6:0:1
6:6:1:6
6:7:0:1
6:7:1:6
6:8:0:1
6:8:1:6
6:9:0:1
6:9:1:6
7:0:0:0
7:0:1:7
7:0:2:14
7:0:3:21
7:0:4:28
7:0:5:35
7:0:6:42
7:0:7:49
7:0:8:56
7:0:9:63
7:1:0:1
7:1:1:7
7:1:2:49
7:1:3:343
7:1:4:2401
7:1:5:16807
7:1:6:117649
7:1:7:823543
7:1:8:5764801
7:1:9:40353607
7:2:0:1
7:2:1:7
7:2:2:823543
7:3:0:1
7:3:1:7
7:4:0:1
7:4:1:7
7:5:0:1
7:5:1:7
7:6:0:1
7:6:1:7
7:7:0:1
7:7:1:7
7:8:0:1
7:8:1:7
7:9:0:1
7:9:1:7
8:0:0:0
8:0:1:8
8:0:2:16
8:0:3:24
8:0:4:32
8:0:5:40
8:0:6:48
8:0:7:56
8:0:8:64
8:0:9:72
8:1:0:1
8:1:1:8
8:1:2:64
8:1:3:512
8:1:4:4096
8:1:5:32768
8:1:6:262144
8:1:7:2097152
8:1:8:16777216
8:1:9:134217728
8:2:0:1
8:2:1:8
8:2:2:16777216
8:3:0:1
8:3:1:8
8:4:0:1
8:4:1:8
8:5:0:1
8:5:1:8
8:6:0:1
8:6:1:8
8:7:0:1
8:7:1:8
8:8:0:1
8:8:1:8
8:9:0:1
8:9:1:8
9:0:0:0
9:0:1:9
9:0:2:18
9:0:3:27
9:0:4:36
9:0:5:45
9:0:6:54
9:0:7:63
9:0:8:72
9:0:9:81
9:1:0:1
9:1:1:9
9:1:2:81
9:1:3:729
9:1:4:6561
9:1:5:59049
9:1:6:531441
9:1:7:4782969
9:1:8:43046721
9:1:9:387420489
9:2:0:1
9:2:1:9
9:2:2:387420489
9:3:0:1
9:3:1:9
9:4:0:1
9:4:1:9
9:5:0:1
9:5:1:9
9:6:0:1
9:6:1:9
9:7:0:1
9:7:1:9
9:8:0:1
9:8:1:9
9:9:0:1
9:9:1:9
